<?php

namespace app\logic\user;

use app\common\enum\CreatorEnum;
use app\common\enum\user\UserFollowTypeEnum;
use app\common\model\User;
use app\common\model\user\CreatorApply;
use app\common\model\user\Recommend;
use app\common\model\UserFollow;
use app\logic\BaseLogic;
use app\logic\es\EsUser;
use app\logic\subscribe\SubscribeLogic;
use think\facade\Db;

class UserLogic extends BaseLogic
{

    /**
     * 检查用户是否是创作者
     * @param $userId
     * @return bool
     */
    public static function checkIsCreator($userId): bool
    {
        $value = User::initModel()->where('id', $userId)->value('is_creator');
        return CreatorEnum::from($value) === CreatorEnum::CREATOR;
    }

    /**
     * 关注
     * @param array $userInfo 用户信息
     * @param string $followeeId 被关注者
     * @param $type
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function follow( $userInfo, string $followeeId, $type): bool
    {
        $followerId = $userInfo['id'];
        //查询被关注者
        $followee = User::initModel()
            ->where('id', $followeeId)
            ->where('status', 'enable')
            ->find();

        if (!$followee) {
            throw new \RuntimeException(__('User does not exist'));
        }

        //当前用户不是达人的时候才需要检查被关注的人是不是达人
        if ($userInfo['is_creator'] != CreatorEnum::CREATOR->value && $followee->is_creator !== CreatorEnum::CREATOR->value) {
            throw new \RuntimeException(__('Not the creator'));
        }

        //检查是否已经关注
        $userFollow = new UserFollow();
        $isFollowed = $userFollow->where('follower_id', $followerId)
            ->where('followee_id', $followeeId)
            ->count();

        //取消关注
        if ($isFollowed && UserFollowTypeEnum::from($type) === UserFollowTypeEnum::CANCEL) {
            $userFollow->where('follower_id', $followerId)->where('followee_id', $followeeId)->delete();
        }

        //插入关注记录
        if (!$isFollowed && UserFollowTypeEnum::from($type) === UserFollowTypeEnum::FOLLOW) {
            $userFollow->insert([
                'follower_id' => $followerId,
                'followee_id' => $followeeId,
                'create_time' => time()
            ]);
        }

        return true;
    }

    /**
     * 小费统计
     * @param $userId
     * @return int
     */
    public function tips($userId): int
    {
        //美金
        return 100;
    }

    /**
     * 搜索用户
     * @param array $params 参数
     * @param mixed $userId 当前登录用户id
     * @return array|\Elastic\Elasticsearch\Response\Elasticsearch|\Http\Promise\Promise
     * @throws \Elastic\Elasticsearch\Exception\ClientResponseException
     * @throws \Elastic\Elasticsearch\Exception\ServerResponseException
     */
    public function search($params, $userId)
    {
        // 构建查询体
        $body = [
            'query' => [
                'multi_match' => [
                    'query' => $params['query'],  // 搜索的关键词
                    'fields' => [
                        'nickname.chinese',  // 中文字段
                        'nickname.english',  // 英文字段（不区分大小写）
                        'nickname.ngram'     // 其他语言字段
                    ],
                    'type' => 'best_fields',
                    'operator' => 'and'    // 匹配所有单词
                ]
            ],
            'from' => $params['from'] ?? 0,
            'size' => $params['size'] ?? 10,
            'highlight' => [
                'pre_tags' => ['<span style="color:#FF0055;">'],  // 高亮前缀标签
                'post_tags' => ['</span>'],  // 高亮后缀标签
                'fields' => [
                    'nickname' => new \stdClass(),
                    'nickname.chinese' => new \stdClass(),
                    'nickname.english' => new \stdClass(),
                    'nickname.ngram' => new \stdClass()
                ]
            ]
        ];

        //没有搜索词
        if (empty($params['query'])) {
            return ['total' => 0, 'page_size' => $params['size'], 'list' => []];
        }


        // 执行搜索
        $response = EsUser::getInstance()->search($body);

        $result = $response->asArray();

        if (empty($result['hits'])) {
            throw new \RuntimeException(__('No results found'));
        }
        $total = $result['hits']['total']['value'] ?? 0;
        $data = $result['hits']['hits'] ?? [];

        $list = [];
        $queryLanguage = \think\facade\Lang::getLangSet();

        foreach ($data as $row) {
            $temp = $row['_source'];
            $highlight  = $row['highlight'] ?? [];

            // 根据查询语言选择合适的高亮字段
            if ($queryLanguage == 'zh-cn') {
                // 如果查询是中文，优先选择中文高亮
                if (isset($highlight['nickname.chinese'])) {
                    $highlightedNickname['nickname'] = $highlight['nickname.chinese'];
                    unset($highlight['nickname.chinese']);
                }
            } elseif ($queryLanguage == 'en') {
                // 如果查询是英文，优先选择英文高亮
                if (isset($highlight['nickname.english'])) {
                    $highlightedNickname['nickname'] = $highlight['nickname.english'];
                    unset($highlight['nickname.english']);
                }
            }

            // 如果没有中文或英文的高亮，选择 ngram 字段
            if (empty($highlightedNickname) && isset($highlight['nickname.ngram'])) {
                $highlightedNickname['nickname'] =  $highlight['nickname.ngram'];
                unset($highlight['nickname.ngram']);
            }

            // 合并所有的高亮内容，确保高亮内容的唯一性
            if (!empty($highlightedNickname)) {
                // 选择第一个有效的高亮内容作为最终的nickname
                $highlight = $highlightedNickname;
            }

            $temp['highlight'] = $highlight;
            $temp['is_creator'] = intval($temp['is_creator']);
            $temp['vip'] = intval($temp['vip']);
            $temp['account_type'] = intval($temp['account_type']);
            $temp['is_subscribe'] = SubscribeLogic::getInstance()->isSubscribe($temp['id'], $userId);
            $list[] = $temp;
        }


        return ['total' => $total, 'page_size' => $params['size'], 'list' => $list];
    }

    /**
     * @return array
     * @throws \Elastic\Elasticsearch\Exception\ClientResponseException
     * @throws \Elastic\Elasticsearch\Exception\ServerResponseException
     */
    public function getRecommend()
    {
        $userIds = Recommend::order(DB::raw('RAND()'))->limit(10)->field('user_id')->column('user_id');
        $body = [
            'query' => [
                'terms' => [
                    '_id' => $userIds  // 传入多个 ID
                ]
            ]
        ];
        $esData = EsUser::getInstance()->search($body);

        $esData = $esData->asArray();
        if (empty($esData['hits']['hits'])) {
            return [];
        }

        $list = [];
        foreach ($esData['hits']['hits'] as $row) {
            $list[] = $row['_source'];
        }
        shuffle($list);
        return $list;
    }


    /**
     * 创作者申请
     * @param $uid
     * @param $params
     * @return bool
     * @throws \Throwable
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function creatorApply($uid, $params): bool
    {
        $model = new CreatorApply();

        try {
            $model->startTrans();
            $user = User::initModel()->where('id', $uid)->find();
            if (CreatorEnum::from($user->is_creator) === CreatorEnum::CREATOR) {
                throw new \RuntimeException(__('Already a creator'));
            }
            $check = CreatorApply::where(['user_id' => $uid])->order('id', 'desc')->find();

            if (!empty($check) && $check['status'] == 0) {
                throw new \RuntimeException(__('Please do not apply repeatedly'));
            }
            $data = [
                'user_id' => $uid,
                'document_type' => $params['document_type'],
                'document_images' => join(',', $params['document_images']),
                'images' => join(',', $params['images']),
                'video' => join(',', $params['video']),
            ];
            $model->save($data);
            $model->commit();
            $user->motto = $params['motto'];
            $user->save();
        } catch (\Throwable $e) {
            custom_log('申请创作者失败：' . $e->getMessage());
            $model->rollback();
            throw $e;
        }

        return true;
    }
}